淺談 Git 的 Merge 和 Rebase 的差異
TLDR
git merge保留完整分支歷程與合併節點,適合異質性分支(如main與develop)合併。git rebase改寫歷程以維持線性結構,適合在推送至遠端前的本地分支整理。git merge最多僅需解決一次衝突;git rebase在移動每個 Commit 時皆可能觸發衝突,需多次解決。- 嚴禁在共用分支執行
git rebase,以免改寫歷程導致團隊協作衝突。 git pull --rebase可避免因同步遠端變更而產生不必要的合併 Commit。
合併分支的兩種方式
在 Git 中,合併分支主要有 git merge 與 git rebase 兩種策略,兩者對 Commit History 的影響截然不同。
git merge
什麼情況下會遇到:當需要將兩個不同目標的分支(如 main 與 develop)進行整合時。
- 運作原理:將一個分支的變更合併至目標分支,並產生一個新的合併 Commit。
- 優點:保留完整的歷程記錄與合併時間點;在異質分支合併時,結構清晰。
- 缺點:頻繁合併會導致歷程複雜;產生過多不必要的合併 Commit。
- 衝突處理:僅需判斷與目標分支最新 Commit 的差異,最多只需解決一次衝突。
git rebase
什麼情況下會遇到:當需要整理本地分支的 Commit 歷程,使其看起來像是直接從目標分支延伸出來時。
- 運作原理:將當前分支的 Commit 移動到目標分支的頂端,藉此改寫歷程。
- 優點:使 Commit 歷程保持簡潔、線性。
- 缺點:改寫歷程會導致失去原始合併點;若在共用分支使用,會造成團隊協作混亂。
- 衝突處理:在移動每個 Commit 的過程中,若該 Commit 與基底分支發生衝突,則需逐一解決,可能導致多次衝突處理。
分支圖示例
以下透過 Mermaid 視覺化展示操作差異:
原本的分支歷程:
Merge 的結果:
Rebase 的結果:
使用時機與建議
分支同質性判斷
- 同質性分支:指同一分支的遠端與本地版本(如
origin/main與main)。建議使用git rebase。 - 異質性分支:指目標不同的分支(如
main與develop)。建議使用git merge。
實務建議
- 同步遠端變更:
git pull本質是fetch加merge。建議使用git pull --rebase,將本地變更整合至遠端變更之上,避免產生不必要的合併 Commit。 - 發送 MR/PR 前:建議先使用
git rebase將分支移至目標分支最新狀態,確保無衝突後再發送。 - 進階操作:可使用
git rebase -interactive {起始 Commit}進行 Commit 合併、順序調整或訊息修改。
TIP
有關解決衝突的權責應該是在審核者還是 MR 提交者,不同團隊作法不同,請依各團隊規定。
WARNING
除了 git pull --rebase 以外,Rebase 相關操作應僅用於自身開發的分支上進行,請勿在共用的分支上操作。
對共用分支的 Rebase 操作應僅在尚未執行 git push 前執行,因為一旦 git push 又變更本地儲存庫的 Commit 歷程,會導致本地與遠端的歷程不一致,如果使用 git push --force 強制變更遠端儲存庫,則會換成其他人的本地遠端儲存庫歷程和不一致。這樣的操作不僅影響團隊協作,還可能引發爭議。
異動歷程
- 初版文件建立。